import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


class Server implements Runnable {
	private ExecutorService executor = Executors.newCachedThreadPool();

	private static ServerSocket s;
	//UserDB
	private UserDB userdb = new UserDB();
	//AuktionsDB
	private AuctionManager auct = new AuctionManager();
	//SessionDB
	private ArrayList<ClientSession> sessionDB = new ArrayList<ClientSession>();
	
	//Constructor
	public Server(int tcpport){
		try {
			//TCPSocket
			s = new ServerSocket(tcpport);
			
			//Thread fuer eingehende Verbindungen
			Thread listen = new Thread(this);
	    	listen.start();
			
	    	
	    	//Interkative Eingabe zum herunterfahren des Servers
			Scanner sc = new Scanner(System.in);
			while(true){
				if (sc.nextLine().equals("")){
					System.out.println("Interactive command: Shutdown Server");
					
					//Shudown Threadpool
					executor.shutdown();
					
					//Beenden der laufenden Auktionen
					auct.StopAllforShutdown();
					
					//Alle verbundenen Clients disconnecten
					for(int i=0; i<sessionDB.size();i++){
						sessionDB.get(i).sendShutdownNotification();
						sessionDB.get(i).closeStreams();
					}
					try{
						s.close();
					}
					catch (SocketException e){
						System.out.println("Error: Socket closing");
					}
					break;
				}
			}
			
		} 
		catch (IOException e) {
			System.out.println("Can't initialize Socketconnection");
		}
		
	
		
	}
	@Override
	public void run() {
		
			try {
				while (true){
					Socket tempsoc;
					//Accept eingehende Verbindung
					tempsoc = s.accept();
					//Uebergebe Verbindungsdaten an neue Session
					ClientSession newSession = new ClientSession(tempsoc,userdb,auct,sessionDB);
					sessionDB.add(newSession);
					//Verwende fuer neue Session einen Thread aus Threadpool
					executor.execute(newSession);
				}
			} catch (IOException e) {
				System.out.println("Server successfully shut down!");
			}		
	}
	
	
	public static void main(String[] args) {
		//Parameterpruefung
		if(args.length==1){
			try{
				//Neue Instanz vom Server mit Parameter
				new Server(Integer.parseInt(args[0]));
			}
			catch (NumberFormatException e){System.out.println("Usage: java Server <TCPPort>");}
			
		}
		else{
			//Usage
			System.out.println("Usage: java Server <TCPPort>");
		}
	}
	

	

}
